package com.yr.ryjk.consult.service;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import com.alibaba.fastjson.JSONObject;
import com.yr.ryjk.coin.dao.CoinRecordMapper;
import com.yr.ryjk.coin.entity.CoinRecord;
import com.yr.ryjk.common.Constant;
import com.yr.ryjk.common.ErrorType;
import com.yr.ryjk.common.Pagination;
import com.yr.ryjk.consult.dao.ConsultMapper;
import com.yr.ryjk.consult.dao.ConsultReplyMapper;
import com.yr.ryjk.consult.entity.Consult;
import com.yr.ryjk.consult.entity.ConsultReply;
import com.yr.ryjk.consult.vo.ConsultVO;
import com.yr.ryjk.doctor.dao.DoctorMapper;
import com.yr.ryjk.doctor.entity.Doctor;
import com.yr.ryjk.jpush.JPushType;
import com.yr.ryjk.jpush.JpushMessage;
import com.yr.ryjk.jpush.JpushSendService;
import com.yr.ryjk.redis.JedisUtil;
import com.yr.ryjk.user.dao.UserMapper;
import com.yr.ryjk.user.entity.User;
import com.yr.ryjk.util.IDGenerator;
import com.yr.ryjk.util.JSONUtil;

@Service
public class ConsultService implements IConsultService{
	@Autowired
    private ConsultMapper consultMapper;
	@Autowired
	private ConsultReplyMapper consultReplyMapper;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private DoctorMapper doctorMapper;
	@Autowired
	private CoinRecordMapper coinRecordMapper;

	@Override
	public Map<String, Object> addConsult(Consult consult,String phone)throws IllegalAccessException, InvocationTargetException {
		User user = userMapper.selectUserByPhone(phone);
		final Doctor doctor = doctorMapper.selectByPrimaryKey(consult.getDocId());
		
		if(user != null&&doctor!=null){
			int userCoin = user.getCoin(),askPrice = doctor.getAskPrice();
			if(userCoin >= askPrice){         //健康币足够
				//1.健康币md5验证
				if(!DigestUtils.md5DigestAsHex((userCoin+Constant.COIN_MD5_SECRET_KEY).getBytes()).equals(user.getCoinMd5())){
					return JSONUtil.getJSON(ErrorType.COIN_MD5_CHECK_ERROR);
				}
				
				//2.设置属性
				consult.setId(IDGenerator.gen32UUID());
				consult.setStatus(0);
				consult.setUserId(user.getId());
				consult.setAddTime(new Date());
				consult.setCostCoin(doctor.getAskPrice());//花费健康币

				//3.扣币	
				int coin=user.getCoin()-askPrice;
				userMapper.updateCoinById(coin,
						DigestUtils.md5DigestAsHex((coin+Constant.COIN_MD5_SECRET_KEY).getBytes()),
						user.getId());
				//4.健康币操作记录
				if(askPrice>0){
					CoinRecord cr=new CoinRecord();
					cr.setCoinRecordId(IDGenerator.gen32UUID());
					cr.setUserId(user.getId());
					cr.setOperateTime(new Date());
					cr.setType(0);
					cr.setCount(askPrice);
					cr.setContent("咨询医生"+doctor.getRealName()+"消耗"+askPrice+"个健康币");
					coinRecordMapper.insert(cr);
				}
				
				//5.保存
				consultMapper.insert(consult);
				
				//6.推送通知(极光推送--透传)
				final JpushMessage msg = new JpushMessage();
				msg.setName(user.getName());
				msg.setTitle(consult.getTitle());
				msg.setType(JPushType.add_consult);
				msg.setConsultId(consult.getId());
				
				new Thread(new Runnable() {              //新开线程，避免阻塞
					@Override
					public void run() {
						try {
							String jpDevice  = JedisUtil.getJPushKeyByPhone(doctor.getPhone());
							String jpushMap =  JSONObject.toJSON(msg).toString();
							JpushSendService.sendAndroidMessage(jpushMap, new String[]{jpDevice});
						} catch (Exception e) {
							e.printStackTrace();
							//消息推送异常,是可以允许的异常
						}
					}
				}).start();
				ConsultVO consultVO=consultMapper.selectVoById(consult.getId());
				return JSONUtil.getJSON(ErrorType.SUCCESS,consultVO);
			}else{
				return JSONUtil.getJSON(ErrorType.COIN_NOT_ENOUGH_ERROR);
			}			
		}else{
			return JSONUtil.getJSON(ErrorType.REQUESTED_DATA_NOT_EXIST_ERROR);
		}
	}
	
	@Override
	public Map<String, Object> getListOfUser(int pageNo, int pageSize, int status,String token) {
		status=(status==0?1:(status==1?0:status));         //为统一app端的处理，做一下反转，来保持和doctor一致
		//1.根据token找到user
		String phone=JedisUtil.getPhoneByToken(token);
		User user=userMapper.selectUserByPhone(phone);
		if(user==null){
			return JSONUtil.getJSON(ErrorType.AUTHORITY_ERROR);
		}else {
			String id=user.getId();
			
			//2.返回数据
			int count=consultMapper.selectCount(status,id);
			List<ConsultVO> list =consultMapper.selectVoListOfUser((pageNo-1)*pageSize,pageSize,status,id);

			Map<String, Object> map=new HashMap<String, Object>();
			map.put("list", list);
			map.put("pagination", new Pagination(pageSize,pageNo,count));
			
			return map;
		}
	}

	@Override
	public Map<String, Object> getListOfDoctor(int pageNo, int pageSize, int status,
			String token) {
		//1.根据token找到doctor
		String phone=JedisUtil.getPhoneByToken(token);
		Doctor doctor=doctorMapper.selectByPhone(phone);
		if(doctor==null){
			return JSONUtil.getJSON(ErrorType.AUTHORITY_ERROR);
		}else {
			String id=doctor.getId();
			
			List<ConsultVO> list =consultMapper.selectVoListOfDoctor((pageNo-1)*pageSize,pageSize,status,id);
			int count=consultMapper.selectCountOfDoctor(status,id);
			
			Map<String, Object> map=new HashMap<String, Object>();
			map.put("list", list);
			map.put("pagination", new Pagination(pageSize,pageNo,count));
			
			return map;
		}
	}

	@Override
	public Map<String, Object> getContentList(int pageNo, int pageSize, String id) {
		ConsultVO consult=consultMapper.selectVoById(id);
		int count=consultReplyMapper.selectCount(id);
		List<ConsultReply> list = consultReplyMapper.selectByConsultId((pageNo-1)*pageSize,pageSize,id);
		
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("list", list);
		map.put("pagination", new Pagination(pageSize, pageNo, count));
		map.put("consult", consult);
		return map;
	}

	@Override
	public Map<String, Object> addReply(String id, Integer type,int isPush,
			String answerContent, String picUrls) {
		Consult consult=consultMapper.selectByPrimaryKey(id);
		switch (consult.getStatus()) {
		case 0:
		case 1:
			//1.更新状态
			if(isPush!=0){
				consult.setStatus(type);
				consultMapper.updateStatusById(consult);
			}
			
			//2.插入reply记录
			ConsultReply reply=new ConsultReply();
			reply.setType(type);
			reply.setAnswerContent(answerContent);
			reply.setPicUrls(picUrls);
			reply.setAnswerTime(new Date());
			reply.setConId(consult.getId());
			
			consultReplyMapper.insert(reply);
		
			//3.极光推送--透传
			if(isPush!=0){
				jpushMsg(consult,type);
			}

			//4.是否倒计时进行自动结束,如果是用户,则清除倒计时
			if(type==1){
				JedisUtil.putConsultTimerMap(consult.getId());
			}else {   //用户
				JedisUtil.delTimeByConsultId(consult.getId());
			}
			break;
		case 2:
			return JSONUtil.getJSON(ErrorType.CONSULT_HAS_END_ERROR);
		default:
			break;
		}
		return JSONUtil.getJSON(ErrorType.SUCCESS);
	}

	public void jpushMsg(final Consult consult,final Integer type){
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				JpushMessage msg = new JpushMessage();	
				User user = userMapper.selectByPrimaryKey(consult.getUserId());
				Doctor doctor = doctorMapper.selectByPrimaryKey(consult.getDocId());
				String jpDevice  = "";
				String jpushMap  = "";
				switch (type) {
				case 0:
					jpDevice = JedisUtil.getJPushKeyByPhone(doctor.getPhone());
					msg.setName(user.getName());
					msg.setTitle(consult.getTitle());
					msg.setConsultId(consult.getId());
					msg.setType(JPushType.add_reply);
					
					jpushMap =  JSONObject.toJSON(msg).toString();
					JpushSendService.sendAndroidMessage(jpushMap, new String[]{jpDevice});
					break;
				case 1:
					jpDevice = JedisUtil.getJPushKeyByPhone(user.getPhone());
					msg.setName(doctor.getRealName());
					msg.setTitle(consult.getTitle());
					msg.setConsultId(consult.getId());
					msg.setType(JPushType.add_reply);
					
					jpushMap =  JSONObject.toJSON(msg).toString();
					JpushSendService.sendAndroidMessage(jpushMap, new String[]{jpDevice});
					break;
				default:
					break;
				}
			}
		}).start();
	}
	
	@Override
	public void updateEnd(String id,String jpushType) {
		//1.设置状态=2 
		Consult consult = consultMapper.selectByPrimaryKey(id);
		consult.setStatus(2);
		consultMapper.updateByPrimaryKey(consult);
		
		//2.加健康币
		Doctor doctor = doctorMapper.selectByPrimaryKey(consult.getDocId());
		int newCoin=doctor.getCoin()+consult.getCostCoin();
		String coinMd5=DigestUtils.md5DigestAsHex((newCoin+Constant.COIN_MD5_SECRET_KEY).getBytes());
		doctorMapper.updateCoinById(newCoin, coinMd5, doctor.getTotalGainCoin()+consult.getCostCoin(), doctor.getId());
		
		//3.coin操作记录
		User user=userMapper.selectByPrimaryKey(consult.getUserId());
		if(consult.getCostCoin()>0){
			CoinRecord cr=new CoinRecord();
			cr.setCoinRecordId(IDGenerator.gen32UUID());
			cr.setUserId(doctor.getId());
			cr.setOperateTime(new Date());
			cr.setType(1);
			cr.setCount(consult.getCostCoin());
			cr.setContent("解决"+user.getName()+"的咨询获得"+consult.getCostCoin()+"个健康币");
			
			coinRecordMapper.insert(cr);
		}
		
		//4.删除自动确认的倒计时
		JedisUtil.delTimeByConsultId(consult.getId());
		
		//5.极光推送--透传
		final String jpDevice  = JedisUtil.getJPushKeyByPhone(doctor.getPhone());
		
		JpushMessage msg = new JpushMessage();		
		msg.setName(user.getName());
		msg.setTitle(consult.getTitle());
		msg.setConsultId(id);
		msg.setType(jpushType);

		final String jpushMap =  JSONObject.toJSON(msg).toString();
		new Thread(new Runnable() {
			@Override
			public void run() {
				JpushSendService.sendAndroidMessage(jpushMap, new String[]{jpDevice});
			}
		}).start();
	}

	@Override
	public Object getListHistory(int pageNo, int pageSize, String consultId) {
		Consult c=consultMapper.selectByPrimaryKey(consultId);
		
		List<ConsultVO> list=consultMapper.selectHistoryOfDoctorAndUser(c.getDocId(),c.getUserId(),(pageNo-1)*pageSize,pageSize);
		int count=consultMapper.selectCountHistory(c.getDocId(),c.getUserId());
		User user=userMapper.selectByPrimaryKey(c.getUserId());
		
		Map<String, Object> map=new HashMap<String,Object>();
		map.put("user", user);
		map.put("list", list);
		map.put("pagination", new Pagination(pageSize, pageNo, count));
		
		return map;
	}

	@Override
	public void askForEnd(String id) {
		Consult consult	= consultMapper.selectByPrimaryKey(id);
		User user = userMapper.selectByPrimaryKey(consult.getUserId());
		Doctor doctor=doctorMapper.selectByPrimaryKey(consult.getDocId());
		//极光推送--透传
		final String jpDevice  = JedisUtil.getJPushKeyByPhone(user.getPhone());
		
		JpushMessage msg = new JpushMessage();		
		msg.setName(doctor.getRealName());
		msg.setTitle(consult.getTitle());
		msg.setConsultId(id);
		msg.setType(JPushType.ask_for_end);

		final String jpushMap =  JSONObject.toJSON(msg).toString();
		new Thread(new Runnable() {
			@Override
			public void run() {
				JpushSendService.sendAndroidMessage(jpushMap, new String[]{jpDevice});
			}
		}).start();
	}

	@Override
	public void refuseEnd(String id) {
		Consult consult	= consultMapper.selectByPrimaryKey(id);
		Doctor doctor = doctorMapper.selectByPrimaryKey(consult.getDocId());
		User user=userMapper.selectByPrimaryKey(consult.getUserId());
		//极光推送--透传
		final String jpDevice  = JedisUtil.getJPushKeyByPhone(doctor.getPhone());
		
		JpushMessage msg = new JpushMessage();		
		msg.setName(user.getName());
		msg.setTitle(consult.getTitle());
		msg.setConsultId(id);
		msg.setType(JPushType.refuse_end);

		final String jpushMap =  JSONObject.toJSON(msg).toString();
		new Thread(new Runnable() {
			@Override
			public void run() {
				JpushSendService.sendAndroidMessage(jpushMap, new String[]{jpDevice});
			}
		}).start();
	}

	@Override
	public Object getUnScoreList(int pageNo, int pageSize, String token) {
		String phone=JedisUtil.getPhoneByToken(token);
		
		List<ConsultVO> list=consultMapper.selectUnScoreList((pageNo-1)*pageSize,pageSize,phone);
		int count=consultMapper.selectUnScoreCount(phone);
		
		Map<String, Object> map=new HashMap<String,Object>();
		map.put("list", list);
		map.put("pagination", new Pagination(pageSize, pageNo, count));
		return map;
	}

	@Override
	public void deleteConsultById(String id) {
		//先删除咨询回复表记录(副表)，然后删除咨询记录表记录（主表）
		consultReplyMapper. deleteConsultReplyById(id);	
		consultMapper. deleteConsultById(id);
	}

	@Override
	public int getUnHandledCount(String token) {
		String phone=JedisUtil.getPhoneByToken(token);
		return consultMapper.selectUnHandledCountOfUser(phone);
	}
}